#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<string>
#include<string.h>
int pipearr[2];//[0] 读  [1] 写
using namespace std;
//模拟实现管道通信
// 1.读写端正常，管道如果为空，读端就要阻塞
// 2.读写端正常，管道如果被写满，写端就要被阻塞
// 3.写端正常写入，读端关闭了。操作系统就要杀掉正在写入的进程
// 4.读端正常读，写端关闭，读端就会读到0，表明读到了文件（pipe）结尾，不会被阻塞

//子进程写
void writer(int fd)
{
    //文件已经打开，直接写入
    string str = "hello I am child";
    char buffer[1024];
    int num=0;
    char ch='c';
    while(1)
    {
       snprintf(buffer,sizeof(buffer),"%s-%d-%d",str.c_str(),getpid(),num++);
       write(fd,buffer,strlen(buffer));
       sleep(1);
        //   write(fd,&ch,1);
        //   num++;
        //   cout<<num<<endl; 
    }
}

//父进程读
void readr(int fd)
{
   
    char buffer[1024];
    int num=0;
    string s="fathar get:";
    int cnt=5;
    while(cnt--)
    {
       // sleep(5); 
       ssize_t n=read(fd,buffer,1024);
       if(n<=0) break;
       cout<<s.c_str()<<" "<<buffer<<endl;
    }
}


int main()
{
    //失败返回-1
    int tmp=pipe(pipearr);  //打开一个管道，返回读和写的文件描述符
    if(tmp==-1)
    {
        perror("pipe");
        return -1;
    }

    //创建子进程
    pid_t id=fork();
    if(id<0)
    {
        perror("fork");
        return 1;
    }
    //子进程：写
    //关闭读端
    else if(id==0)
    {
        close(pipearr[0]);
        writer(pipearr[1]);

        //用完管道就关掉
        close(pipearr[1]);
        exit(0);
    }
    //父进程：读
    //关闭写端
    close(pipearr[1]);
    readr(pipearr[0]);
    close(pipearr[0]);
    //回收子进程
    int status=0;
    pid_t rid=waitpid(id,&status,0);
    if(rid<0)
    {
        perror("waitpid");
        return 2;
    }
    cout<<"exit_code:"<<((status<<8)&0XFF)<<"exit_sig:"<<(status&0x7f)<<endl;
    return 0;
}